﻿using System;
using System.Collections.Specialized;
using PagSeguro.Mvc.Extensions;
using PagSeguro.Mvc.Recursos;

namespace PagSeguro.Mvc
{
    /// <summary>
    /// Dados do cliente que efetuou a compra.
    /// </summary>
    public class Cliente
    {
        #region PROPRIEDADES

        /// <summary>
        /// Get do nome do cliente.
        /// </summary>
        /// <remarks>
        /// CliNome
        /// TIPO......: Alfa-numérico
        /// TAMANHO...: 100
        /// DESCRIÇÃO.: Anotação enviada pelo cliente.
        /// </remarks>
        public string Nome { get; private set; }

        /// <summary>
        /// Get do e-mail do cliente.
        /// </summary>
        /// <remarks>
        /// CliEmail
        /// TIPO......: Alfa-numérico
        /// TAMANHO...: 255
        /// DESCRIÇÃO.: E-mail do cliente.
        /// </remarks>
        public string Email { get; private set; }

        /// <summary>
        /// Get do endereço do cliente.
        /// </summary>
        /// <remarks>
        /// CliEndereco
        /// TIPO......: Alfa-numérico
        /// TAMANHO...: 200
        /// DESCRIÇÃO.: Endereço do cliente.
        /// </remarks>
        public string Endereco { get; private set; }

        /// <summary>
        /// Get do número da residência cliente.
        /// </summary>
        /// <remarks>
        /// CliNumero
        /// TIPO......: Alfa-numérico
        /// TAMANHO...: 10
        /// DESCRIÇÃO.: Número da residência do cliente.
        /// </remarks>
        public Int64 Numero { get; private set; }

        /// <summary>
        /// Get do complemento do endereço do cliente.
        /// </summary>
        /// <remarks>
        /// CliComplemento
        /// TIPO......: Alfa-numérico
        /// TAMANHO...: 100
        /// DESCRIÇÃO.: Complemento do endereço do cliente.
        /// </remarks>
        public string Complemento { get; private set; }

        /// <summary>
        /// Get do bairro do endereço do cliente.
        /// </summary>
        /// <remarks>
        /// CliBairro
        /// TIPO......: Alfa-numérico
        /// TAMANHO...: 100
        /// DESCRIÇÃO.: Bairro do cliente.
        /// </remarks>
        public string Bairro { get; private set; }

        /// <summary>
        /// Get da cidade do endereço do cliente.
        /// </summary>
        /// <remarks>
        /// CliCidade
        /// TIPO......: Alfa-numérico
        /// TAMANHO...: 100
        /// DESCRIÇÃO.: Cidade do cliente.
        /// </remarks>
        public string Cidade { get; private set; }

        /// <summary>
        /// Get do estado (UF) do endereço do cliente.
        /// </summary>
        /// <remarks>
        /// CliEstado
        /// TIPO......: Alfa-numérico
        /// TAMANHO...: 2
        /// DESCRIÇÃO.: Estado do cliente.
        /// </remarks>
        public string Estado { get; private set; }

        /// <summary>
        /// Get do CEP do endereço do cliente. Formato: 00000000.
        /// </summary>
        /// <remarks>
        /// CliCEP
        /// TIPO......: Alfa-numérico
        /// TAMANHO...: 10
        /// DESCRIÇÃO.: CEP do cliente.
        ///             Formato: 00000000
        /// </remarks>
        public string CEP { get; private set; }

        /// <summary>
        /// Get do CEP com máscara. Ex: 99999-999
        /// </summary>
        public string CEPComMascara { get { return CEP.MascaraParaCEP(); } }

        /// <summary>
        /// Get do telefone do cliente. Formato: 0000000000.
        /// </summary>
        /// <remarks>
        /// CliTelefone
        /// TIPO......: Alfa-numérico
        /// TAMANHO...: 16
        /// DESCRIÇÃO.: CEP do cliente.
        ///             Formato: 00 00000000
        /// </remarks>
        public string Telefone { get; private set; }

        /// <summary>
        /// Get do Telefone com máscara. Ex: (99) 9999-9999.
        /// </summary>
        public string TelefoneComMascara { get { return Telefone.MascaraParaTelefoneBR(); } }

        #endregion

        /// <summary>
        /// Construtor
        /// </summary>
        /// <param name="dados">Dados do cliente.</param>
        internal Cliente(NameValueCollection dados) 
        {
            // TODO: Validação das chaves comentadas temporariamente
            //ValidarDadosPost(dados);

            this.Nome = dados[Constantes.CLI_NOME];
            this.Email = dados[Constantes.CLI_EMAIL];
            this.Endereco = dados[Constantes.CLI_ENDERECO];
            this.Numero = dados[Constantes.CLI_NUMERO].ToInt64();
            this.Complemento = dados[Constantes.CLI_COMPLEMENTO];
            this.Bairro = dados[Constantes.CLI_BAIRRO];
            this.Cidade = dados[Constantes.CLI_CIDADE];
            this.Estado = dados[Constantes.CLI_ESTADO];
            this.CEP = dados[Constantes.CLI_CEP];
            this.Telefone = dados[Constantes.CLI_TELEFONE].TiraEspacos();
        }

        /// <summary>
        /// Valida as chaves do dicionário
        /// </summary>
        /// <param name="dados">Dados do cliente.</param>
        private static void ValidarDadosPost(NameValueCollection dados)
        {
            dados.Validar(Constantes.CLI_NOME);
            dados.Validar(Constantes.CLI_EMAIL);
            dados.Validar(Constantes.CLI_ENDERECO);
            dados.Validar(Constantes.CLI_NUMERO);
            dados.Validar(Constantes.CLI_COMPLEMENTO);
            dados.Validar(Constantes.CLI_BAIRRO);
            dados.Validar(Constantes.CLI_CIDADE);
            dados.Validar(Constantes.CLI_ESTADO);
            dados.Validar(Constantes.CLI_CEP);
            dados.Validar(Constantes.CLI_TELEFONE);
        }

        /// <summary>
        /// Exibe o nome do cliente.
        /// </summary>
        /// <returns>Nome do cliente.</returns>
        public override string ToString()
        {
            if (String.IsNullOrWhiteSpace(Email))
                return Nome;
            return String.Format("{0} ({1})", Nome, Email);
        }
    }
}